package com.thesis.project.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import com.thesis.project.domain.Person;
import com.thesis.project.service.PersonService;
import com.thesis.project.domain.Algorithm;
import com.thesis.project.service.AlgorithmService;
import com.thesis.project.domain.Datatype;
import com.thesis.project.service.DatatypeService;
import com.thesis.project.dto.DatatypeDTO;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;


/**
 * Handles and retrieves person request
 */
@Controller
@RequestMapping("/main")
public class MainController {

	protected static Logger logger = Logger.getLogger("controller");
	
	@Resource(name="personService")
	private PersonService personService;
	
	@Resource(name="algorithmService")
	private AlgorithmService algorithmService;
	
	@Resource(name="datatypeService")
	private DatatypeService datatypeService;
	
	/**
	 * Handles and retrieves all persons and show it in a JSP page
	 * 
	 * @return the name of the JSP page
	 */
	
	private static Process mpProcess = null;
	
	@RequestMapping(value = "/hello.htm", method = RequestMethod.GET)
	public ModelAndView server(@RequestParam(value="submit", required=false) String cmd, @RequestParam(value="isStartMB", required=false) String isStartMBStr) throws IOException{
		

		Map<String, Object> myModel = new HashMap<String, Object>();
		String isStartMB = "1";
		String disable = "this.disabled=true;this.form.submit()";
		
		if (isStartMBStr != null && isStartMBStr.equals("1")) {
			isStartMB = "1";
		}

		myModel.put("startMBButton", "");
		myModel.put("stopMBButton", "");
		

		
		if (cmd != null) {
			if (cmd.equalsIgnoreCase("StartMB")) {
				mpProcess = Runtime.getRuntime().exec("C:\\Users\\HAMINHNAM\\workspace\\ServerManagement\\servermapbuilder.cmd");
				logger.info("Returning mapbuilder view");
//				myModel.put("function", "StartMB");
//				myModel.put("disable", "disable");
//				isStartMB = "1";
			}
				if (cmd.equalsIgnoreCase("StopMB")) {
				logger.info("stop mapbuilder view");
				mpProcess.destroy();
				mpProcess = null;
			}
		}
		
		if (mpProcess != null){
			myModel.put("startMBButton", "disabled=\'disabled\"");
			
		} else {
			myModel.put("stopMBButton", "disabled=\'disabled\"");
			
		}

		return new ModelAndView("hello", "model", myModel);

	}
	
//**************
//**************
//	USER MANAGEMENT
//**************
//**************
    @RequestMapping(value = "/persons", method = RequestMethod.GET)
    public String getPersons(Model model) {
    	
    	logger.debug("Received request to show all persons");
    	
    	// Retrieve all persons by delegating the call to PersonService
    	List<Person> persons = personService.getAll();
    	
    	// Attach persons to the Model
    	model.addAttribute("persons", persons);
    	
    	// This will resolve to /WEB-INF/jsp/personspage.jsp
    	return "personspage";
	}
    
    /**
     * Retrieves the add page
     * 
     * @return the name of the JSP page
     */
    @RequestMapping(value = "/persons/add", method = RequestMethod.GET)
    public String getAdd(Model model) {
    	logger.debug("Received request to show add page");
    
    	// Create new Person and add to model
    	// This is the formBackingOBject
    	model.addAttribute("personAttribute", new Person());

    	// This will resolve to /WEB-INF/jsp/addpage.jsp
    	return "addpage";
	}
 
    /**
     * Adds a new person by delegating the processing to PersonService.
     * Displays a confirmation JSP page
     * 
     * @return  the name of the JSP page
     */
    @RequestMapping(value = "/persons/add", method = RequestMethod.POST)
    public String add(@ModelAttribute("personAttribute") Person person) {
		logger.debug("Received request to add new person");
		
    	// The "personAttribute" model has been passed to the controller from the JSP
    	// We use the name "personAttribute" because the JSP uses that name
		
		// Call PersonService to do the actual adding
		personService.add(person);

    	// This will resolve to /WEB-INF/jsp/addedpage.jsp
		return "addedpage";
	}
    
    /**
     * Deletes an existing person by delegating the processing to PersonService.
     * Displays a confirmation JSP page
     * 
     * @return  the name of the JSP page
     */
    @RequestMapping(value = "/persons/delete", method = RequestMethod.GET)
    public String delete(@RequestParam(value="id", required=true) Integer id, 
    										Model model) {
   
		logger.debug("Received request to delete existing person");
		
		// Call PersonService to do the actual deleting
		personService.delete(id);
		
		// Add id reference to Model
		model.addAttribute("id", id);
    	
    	// This will resolve to /WEB-INF/jsp/deletedpage.jsp
		return "deletedpage";
	}
    
    /**
     * Retrieves the edit page
     * 
     * @return the name of the JSP page
     */
    @RequestMapping(value = "/persons/edit", method = RequestMethod.GET)
    public String getEdit(@RequestParam(value="id", required=true) Integer id,  
    										Model model) {
    	logger.debug("Received request to show edit page");
    
    	// Retrieve existing Person and add to model
    	// This is the formBackingOBject
    	model.addAttribute("personAttribute", personService.get(id));
    	
    	// This will resolve to /WEB-INF/jsp/editpage.jsp
    	return "editpage";
	}
    
    /**
     * Edits an existing person by delegating the processing to PersonService.
     * Displays a confirmation JSP page
     * 
     * @return  the name of the JSP page
     */
    @RequestMapping(value = "/persons/edit", method = RequestMethod.POST)
    public String saveEdit(@ModelAttribute("personAttribute") Person person, 
    										   @RequestParam(value="id", required=true) Integer id, 
    												Model model) {
    	logger.debug("Received request to update person");
    
    	// The "personAttribute" model has been passed to the controller from the JSP
    	// We use the name "personAttribute" because the JSP uses that name
    	
    	// We manually assign the id because we disabled it in the JSP page
    	// When a field is disabled it will not be included in the ModelAttribute
    	person.setId(id);
    	
    	// Delegate to PersonService for editing
    	personService.edit(person);
    	
    	// Add id reference to Model
		model.addAttribute("id", id);
		
    	// This will resolve to /WEB-INF/jsp/editedpage.jsp
		return "editedpage";
	}
    
   
    
    //**************
    //**************
    //RECORDS MANAGEMENT
    //**************
    //**************
      
      @RequestMapping(value = "/records", method = RequestMethod.GET)
      public String getRecords(Model model) {
      	
      	logger.debug("Received request to show all datatypes");
      	
      	// Retrieve all persons by delegating the call to PersonService
      	List<Datatype> datatypes = datatypeService.getAll();
      	
      	// Prepare model object
          List<DatatypeDTO> datatypeDTO = new ArrayList<DatatypeDTO>();
          
          for (Datatype datatype: datatypes) {
  	            // Create new data transfer object
  	         DatatypeDTO dto = new DatatypeDTO();
  	             
  	         dto.setId(datatype.getId());
  	         dto.setDataTypeName(datatype.getDataTypeName());
  	         dto.setDataDescription(datatype.getDataDescription());
  	         dto.setClassName(datatype.getClassName());
  	         dto.setAlgorithm(algorithmService.getAll(datatype.getId()));
  	          
  	         // Add to model list
  	         datatypeDTO.add(dto);
  	          }
      	
      	// Attach persons to the Model
      	model.addAttribute("datatypes", datatypeDTO);
      	
      	// This will resolve to /WEB-INF/jsp/personspage.jsp
      	return "records";
  	}  
    
  //**************
  //**************
  //DATATYPE MANAGEMENT
  //**************
  //**************
    
    @RequestMapping(value = "/datatypes", method = RequestMethod.GET)
    public String getDatatypes(Model model) {
    	
    	logger.debug("Received request to show all datatypes");
    	
    	// Retrieve all persons by delegating the call to PersonService
    	List<Datatype> datatypes = datatypeService.getAll();
    	
    	// Prepare model object
        List<DatatypeDTO> datatypeDTO = new ArrayList<DatatypeDTO>();
        
        for (Datatype datatype: datatypes) {
	            // Create new data transfer object
	         DatatypeDTO dto = new DatatypeDTO();
	             
	         dto.setId(datatype.getId());
	         dto.setDataTypeName(datatype.getDataTypeName());
	         dto.setDataDescription(datatype.getDataDescription());
	         dto.setClassName(datatype.getClassName());
	         dto.setAlgorithm(algorithmService.getAll(datatype.getId()));
	          
	         // Add to model list
	         datatypeDTO.add(dto);
	          }
    	
    	// Attach persons to the Model
    	model.addAttribute("datatypes", datatypeDTO);
    	
    	// This will resolve to /WEB-INF/jsp/personspage.jsp
    	return "datatypepage";
	}
    
    /**
     * Retrieves the add page
     * 
     * @return the name of the JSP page
     */
    @RequestMapping(value = "/datatypes/add", method = RequestMethod.GET)
    public String getDatatypeAdd(Model model) {
    	logger.debug("Received request to show add page");
    
    	// Create new Person and add to model
    	// This is the formBackingOBject
    	model.addAttribute("datatypeAttribute", new Datatype());

    	// This will resolve to /WEB-INF/jsp/addpage.jsp
    	return "adddatatype";
	}
 
    /**
     * Adds a new person by delegating the processing to PersonService.
     * Displays a confirmation JSP page
     * 
     * @return  the name of the JSP page
     */
    @RequestMapping(value = "/datatypes/add", method = RequestMethod.POST)
    public String add(@ModelAttribute("datatypeAttribute") Datatype datatype) {
		logger.debug("Received request to add new datatype");
		
    	// The "personAttribute" model has been passed to the controller from the JSP
    	// We use the name "personAttribute" because the JSP uses that name
		
		// Call PersonService to do the actual adding
		datatypeService.add(datatype);

    	// This will resolve to /WEB-INF/jsp/addedpage.jsp
		return "addeddatatype";
	}
    
    /**
     * Deletes an existing person by delegating the processing to PersonService.
     * Displays a confirmation JSP page
     * 
     * @return  the name of the JSP page
     */
    @RequestMapping(value = "/datatypes/delete", method = RequestMethod.GET)
    public String deleteDatatype(@RequestParam(value="id", required=true) Integer id, 
    										Model model) {
   
		logger.debug("Received request to delete existing datatype");
		
		algorithmService.deleteAll(id);
		
		// Call PersonService to do the actual deleting
		datatypeService.delete(id);
		
		// Add id reference to Model
		model.addAttribute("id", id);
    	
    	// This will resolve to /WEB-INF/jsp/deletedpage.jsp
		return "deleteddatatype";
	}
    
    /**
     * Retrieves the edit page
     * 
     * @return the name of the JSP page
     */
    @RequestMapping(value = "/datatypes/edit", method = RequestMethod.GET)
    public String getEditDatatype(@RequestParam(value="id", required=true) Integer id,  
    										Model model) {
    	logger.debug("Received request to show edit page");
    
    	// Retrieve existing Person and add to model
    	// This is the formBackingOBject
    	model.addAttribute("datatypeAttribute", datatypeService.get(id));
    	
    	// This will resolve to /WEB-INF/jsp/editpage.jsp
    	return "editdatatype";
	}
    
    /**
     * Edits an existing person by delegating the processing to PersonService.
     * Displays a confirmation JSP page
     * 
     * @return  the name of the JSP page
     */
    @RequestMapping(value = "/datatypes/edit", method = RequestMethod.POST)
    public String saveEdit(@ModelAttribute("datatypeAttribute") Datatype datatype, 
    										   @RequestParam(value="id", required=true) Integer id, 
    												Model model) {
    	logger.debug("Received request to update datatype");
    
    	// The "personAttribute" model has been passed to the controller from the JSP
    	// We use the name "personAttribute" because the JSP uses that name
    	
    	// We manually assign the id because we disabled it in the JSP page
    	// When a field is disabled it will not be included in the ModelAttribute
    	datatype.setId(id);
    	
    	// Delegate to PersonService for editing
    	datatypeService.edit(datatype);
    	
    	// Add id reference to Model
		model.addAttribute("id", id);
		
    	// This will resolve to /WEB-INF/jsp/editedpage.jsp
		return "editeddatatype";
	}
    
  //**************
    //**************
    //ALGORITHM MANAGEMENT
    //**************
    //**************
      
      @RequestMapping(value = "/algorithms", method = RequestMethod.GET)
      public String getAlgorithms(Model model) {
      	
      	logger.debug("Received request to show all algorithms");
      	
      	// Retrieve all persons by delegating the call to PersonService
      	List<Algorithm> algorithms = algorithmService.getAll();
      	
      	// Attach persons to the Model
      	model.addAttribute("algorithms", algorithms);
      	
      	// This will resolve to /WEB-INF/jsp/personspage.jsp
      	return "algorithmpage";
  	}
      
      /**
       * Retrieves the add page
       * 
       * @return the name of the JSP page
       */
      @RequestMapping(value = "/algorithms/add", method = RequestMethod.GET)
      public String getAlgorithmAdd(Model model) {
      	logger.debug("Received request to show add page");
      
      	// Create new Person and add to model
      	// This is the formBackingOBject
      	model.addAttribute("algorithmAttribute", new Algorithm());

      	// This will resolve to /WEB-INF/jsp/addpage.jsp
      	return "addalgorithm";
  	}
   
      /**
       * Adds a new person by delegating the processing to PersonService.
       * Displays a confirmation JSP page
       * 
       * @return  the name of the JSP page
       */
      @RequestMapping(value = "/algorithms/add", method = RequestMethod.POST)
      public String add(@ModelAttribute("algorithmAttribute") Algorithm algorithm) {
  		logger.debug("Received request to add new algorithm");
  		
      	// The "personAttribute" model has been passed to the controller from the JSP
      	// We use the name "personAttribute" because the JSP uses that name
  		
  		// Call PersonService to do the actual adding
  		algorithmService.add(algorithm);

      	// This will resolve to /WEB-INF/jsp/addedpage.jsp
  		return "addedalgorithm";
  	}
      
      /**
       * Deletes an existing person by delegating the processing to PersonService.
       * Displays a confirmation JSP page
       * 
       * @return  the name of the JSP page
       */
      @RequestMapping(value = "/algorithms/delete", method = RequestMethod.GET)
      public String deleteAlgorithm(@RequestParam(value="id", required=true) Integer id, 
      										Model model) {
     
  		logger.debug("Received request to delete existing person");
  		
  		// Call PersonService to do the actual deleting
  		algorithmService.delete(id);
  		
  		// Add id reference to Model
  		model.addAttribute("id", id);
      	
      	// This will resolve to /WEB-INF/jsp/deletedpage.jsp
  		return "deletedalgorithm";
  	}
      
      /**
       * Retrieves the edit page
       * 
       * @return the name of the JSP page
       */
      @RequestMapping(value = "/algorithms/edit", method = RequestMethod.GET)
      public String getEditAlgorithm(@RequestParam(value="id", required=true) Integer id,  
      										Model model) {
      	logger.debug("Received request to show edit page");
      
      	// Retrieve existing Person and add to model
      	// This is the formBackingOBject
      	model.addAttribute("algorithmAttribute", algorithmService.get(id));
      	
      	// This will resolve to /WEB-INF/jsp/editpage.jsp
      	return "editalgorithm";
  	}
      
      /**
       * Edits an existing person by delegating the processing to PersonService.
       * Displays a confirmation JSP page
       * 
       * @return  the name of the JSP page
       */
      @RequestMapping(value = "/algorithms/edit", method = RequestMethod.POST)
      public String saveEdit(@ModelAttribute("algorithmAttribute") Algorithm algorithm, 
      										   @RequestParam(value="id", required=true) Integer id, 
      												Model model) {
      	logger.debug("Received request to update person");
      
      	// The "personAttribute" model has been passed to the controller from the JSP
      	// We use the name "personAttribute" because the JSP uses that name
      	
      	// We manually assign the id because we disabled it in the JSP page
      	// When a field is disabled it will not be included in the ModelAttribute
      	algorithm.setId(id);
      	
      	// Delegate to PersonService for editing
      	algorithmService.edit(algorithm);
      	
      	// Add id reference to Model
  		model.addAttribute("id", id);
  		
      	// This will resolve to /WEB-INF/jsp/editedpage.jsp
  		return "editedalgorithm";
  	}
    
}
